#!/usr/bin/python

from datetime import timedelta, time, date, datetime
import serial
from time import sleep

class SleepyTrackerData:

        def parse_bytes(self, bytes):
                today = datetime.today()
            
                # Date
                recMonth = bytes[1]
                recDay = bytes[2]
                recYear = today.year

                # The watch has no year info, so if we're a later month/day is recorded
                # than is possible, we're likely using data from the previous year.
                if recMonth > today.month or (recMonth == today.month and recDay > today.day):
                    recYear = today.year - 1

                self.date = date(recYear, recMonth, recDay)
                self.window = bytes[4] 
                self.to_bed = time(bytes[5], bytes[6])
                self.alarm_time = time(bytes[7], bytes[8])
       
                # Almost awake data
                self.awake_data = []
                for i in xrange(10, 10 + (bytes[9]*3) - 1, 3):
                    awake_time = time(bytes[i], bytes[i+1], bytes[i+2])
                    self.awake_data.append(awake_time)
                
                
                temp_alarm = datetime(recYear, recMonth, recDay, self.alarm_time.hour, self.alarm_time.minute)
                temp_alarm -= timedelta(0, 0, 0, 0, self.window) 
                earliest_wake = time(temp_alarm.hour, temp_alarm.minute)
 
                if self.awake_data[-1] < earliest_wake: 
                    self.wake_up_time = self.alarm_time
                else:
                    self.wake_up_time = self.awake_data[-1]
                
                pos = 10 + (bytes[9]*3)
                dataAVal = bytes[pos+1]*0xff + bytes[pos]
                dataASecs = dataAVal % 60
                dataAMins = (dataAVal-dataASecs)/60
                self.awake_data_a = timedelta(0, dataASecs, 0, 0, dataAMins)
        
        def valid_crc(self, bytes):
                crc = 0
                cnt = 0
                for byte in bytes:
                    cnt = cnt + 1
                    if cnt > 1 and cnt < len(bytes)-1:
                            crc = crc + byte

                crc %= 256

                if crc != bytes[-2]:
                    return False
                return True

        def __init__(self, bytes):
            if not self.valid_crc(bytes):
                raise ValueError('Invalid CRC')

            self.parse_bytes(bytes)

class SleepyTracker:
    def __init__(self, device):
        ser = serial.Serial()
        ser.port = device
        ser.baudrate = 2400
        ser.bytesize = 8
        ser.rtscts = False
        ser.timeout = 0

        ser.open()
        ser.write('V')
        sleep(1)
        str = ser.read(250)
        ser.close()

        bytes = []
        for i in range(len(str)):
            bytes.append(ord(str[i]))

        if len(bytes) < 15:
            raise Exception("Unable to read data. Is the watch connected and in DATA mode?")

        self.data = SleepyTrackerData(bytes)
